/****************************************************************************
 * 	 <SPG2 - Secure Password Generator>
 *   Copyright (C) 2010  <Robert Carr>
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *   
 *   @author Robert Carr (etftw)
 *   @version 2.4
 *   
 ***************************************************************************/

package spg2;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

import PasswordGeneration.Password;

public final class SPG2
{
	private static JFrame jfrWindow;
	private static JCheckBox jcbAlpha, jcbNum, jcbSym;
	private static JLabel jlbCase, jlbLength, jlbPassCount;
	private static JComboBox jcbCase;
	private static JTextField jtfLength, jtfPassCount;
	private static JButton jbtGenerate;
	private static ImagePanel imgLogo;
	private static JMenuBar jmbMenu;
	private static JMenu jmnFile, jmbHelp;
	private static boolean multiple;
	
	/**
	 * Validates the form and creates the required objects to generate and display the new password
	 */
	private static void generatePassword()
	{
		if( jtfLength.getText().length() > 0 )
		{
			if( Integer.parseInt(jtfLength.getText()) <= 0 )
			{
				JOptionPane.showMessageDialog(null, "The length must be atleast 1 character", "Error", JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				if( (! jcbAlpha.isSelected()) && (! jcbNum.isSelected()) && (! jcbSym.isSelected()))
				{
					JOptionPane.showMessageDialog(null, "At least one option must be selected", "Error", JOptionPane.ERROR_MESSAGE);
				}
				else
				{
					if( ! multiple )
					{
						Password password = new Password(jcbAlpha.isSelected(), jcbNum.isSelected(), 
								jcbSym.isSelected(), Integer.parseInt(jtfLength.getText()), jcbCase.getSelectedIndex() + 1);
						PasswordDialog pd = new PasswordDialog(jfrWindow, "Your password is...", password.getPassword());
						pd.setVisible(false);
					}
					else
					{
						if( jtfPassCount.getText().length() > 0 )
						{
							if( Integer.parseInt(jtfPassCount.getText()) <= 0 )
							{
								JOptionPane.showMessageDialog(null, "The number of passwords must be atleast 1", "Error", JOptionPane.ERROR_MESSAGE);
							}
							else
							{
								Password.generateMultiplePasswords(Integer.parseInt(jtfPassCount.getText()), jcbAlpha.isSelected(), jcbNum.isSelected(), 
										jcbSym.isSelected(), Integer.parseInt(jtfLength.getText()), jcbCase.getSelectedIndex() + 1, jfrWindow);
							}
						}
						else
						{
							JOptionPane.showMessageDialog(null, "The number of passwords must be atleast 1", "Error", JOptionPane.ERROR_MESSAGE);
						}
					}
				}
			}
		}
		else
		{
			JOptionPane.showMessageDialog(null, "The length must be atleast 1 character", "Error", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * Instantiates and sets up all the required objects for the GUI
	 */
	private static void createAndShowGUI() 
	{
		// Set multiple password generation to false
		multiple = false;
		
		// Initialise and setup the main JFrame
        jfrWindow = new JFrame("SPG2");
        jfrWindow.setSize(250, 395);
        jfrWindow.setResizable(false);
        jfrWindow.getContentPane().setLayout(null);
        jfrWindow.setLocation((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2,
        		(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 4);
        jfrWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // Initialise and setup the check boxes
        jcbAlpha = new JCheckBox("Include alphabetic characters");
        jcbAlpha.setSelected(true);
        jcbAlpha.setSize(250, 19);
        jcbAlpha.setLocation(13, 125);
        jcbAlpha.setVisible(true);
        jcbNum = new JCheckBox("Include numeric characters");
        jcbNum.setSelected(true);
        jcbNum.setSize(250, 19);
        jcbNum.setLocation(13, 148);
        jcbNum.setVisible(true);
        jcbSym = new JCheckBox("Include symbols");
        jcbSym.setSelected(true);
        jcbSym.setSize(250, 19);
        jcbSym.setLocation(13, 171);
        jcbSym.setVisible(true);
        
        // Initialise and setup the combobox and its label
        jlbCase = new JLabel("Password case");
        jlbCase.setSize(250, 15);
        jlbCase.setLocation(17, 201);
        jlbCase.setVisible(true);
        String[] caseOptions = {"Both (Recommended)", "Lower case", "Upper case"};
        jcbCase = new JComboBox(caseOptions);
        jcbCase.setSelectedIndex(0);
        jcbCase.setSize(192, 21);
        jcbCase.setLocation(17, 217);
        jcbCase.setVisible(true);
        
        // Initialise and setup the length textfield and its label
        jlbLength = new JLabel("Password length");
        jlbLength.setSize(250, 15);
        jlbLength.setLocation(17, 247);
        jlbLength.setVisible(true);
        jtfLength = new JTextField("14");
        jtfLength.setSize(48, 20);
        jtfLength.setLocation(17, 263);
        jtfLength.setVisible(true);
        
        // Initialise and setup the password count textfield and its label
        jlbPassCount = new JLabel("Number of passwords to generate");
        jlbPassCount.setSize(250, 15);
        jlbPassCount.setLocation(17, 290);
        jlbPassCount.setVisible(false);
        jtfPassCount = new JTextField("1");
        jtfPassCount.setSize(48, 20);
        jtfPassCount.setLocation(17, 304);
        jtfPassCount.setVisible(false);
        
        // Initialise and setup the generate button
        jbtGenerate = new JButton("Generate Password");
        jbtGenerate.setSize(210, 31);
        jbtGenerate.setLocation(17, 299);
        jbtGenerate.setVisible(true);
        jbtGenerate.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				generatePassword();
			}
        });
        
        // Initialise the logo
        imgLogo = new ImagePanel(new ImageIcon(SPG2.class.getResource("logo.png")).getImage());
        imgLogo.setLocation(15, 12);
        imgLogo.setVisible(true);
        
        // Build the menus
        jmbMenu = new JMenuBar();
        
        // File menu
        jmnFile = new JMenu("File");
    	JMenuItem menuItem;
    	final JCheckBoxMenuItem cbMenuItem;
    	cbMenuItem = new JCheckBoxMenuItem("Generaste multiple passwords");
    	cbMenuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_M, ActionEvent.ALT_MASK));
    	cbMenuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				if( ! multiple )
				{
					jlbPassCount.setVisible(true);
					jtfPassCount.setVisible(true);
					jfrWindow.setSize(250, 435);
					jbtGenerate.setText("Generate Passwords");
					jbtGenerate.setLocation(17, 335);
					multiple = true;
				}
				else
				{
					jlbPassCount.setVisible(false);
					jtfPassCount.setVisible(false);
					jbtGenerate.setLocation(17, 299);
					jbtGenerate.setText("Generate Password");
					jfrWindow.setSize(250, 395);
					multiple = false;
				}
			}
    	});
    	menuItem = new JMenuItem("Reset options", KeyEvent.VK_R);
    	menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_R, ActionEvent.ALT_MASK));
    	menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				if( multiple )
					cbMenuItem.doClick();
				
		        jcbAlpha.setSelected(true);
		        jcbNum.setSelected(true);
		        jcbSym.setSelected(true);
		     
		        jcbCase.setSelectedIndex(0);
		        
		        jtfLength.setText("14");
			}
    	});
    	jmnFile.add(cbMenuItem);
    	jmnFile.add(menuItem);
    	jmnFile.insertSeparator(1);
    	jmnFile.insertSeparator(3);
    	menuItem = new JMenuItem("Exit", KeyEvent.VK_E);
    	menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_E, ActionEvent.ALT_MASK));
    	menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				jfrWindow.dispose();
			}
    	});
    	jmnFile.add(menuItem);
    	
    	// Help menu
    	jmbHelp = new JMenu("Help");
    	menuItem = new JMenuItem("About SPG2", KeyEvent.VK_A);
    	menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_A, ActionEvent.ALT_MASK));
    	menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				AboutDialog about = new AboutDialog(jfrWindow);
				about.setVisible(false);
			}
    	});
    	jmbHelp.add(menuItem);
    	
    	jmbMenu.add(jmnFile);
    	jmbMenu.add(jmbHelp);
    	
    	jfrWindow.setJMenuBar(jmbMenu);
        jfrWindow.getContentPane().add(jcbAlpha);
        jfrWindow.getContentPane().add(jcbNum);
        jfrWindow.getContentPane().add(jcbSym);
        jfrWindow.getContentPane().add(jlbCase);
        jfrWindow.getContentPane().add(jcbCase);
        jfrWindow.getContentPane().add(jlbLength);
        jfrWindow.getContentPane().add(jtfLength);
        jfrWindow.getContentPane().add(jlbPassCount);
        jfrWindow.getContentPane().add(jtfPassCount);
        jfrWindow.getContentPane().add(jbtGenerate);
        jfrWindow.getContentPane().add(imgLogo);
        jfrWindow.setVisible(true);
	}
	
	/**
	 * The entry point of the program
	 * @param args arguements
	 */
	public static void main(String[] args) 
	{
		//Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
	}
}
